package com.totoro.tyrank.handle;

import lombok.ToString;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 通用缓存分页器，用于对列表进行分页处理
 *
 * @param <T> 分页数据的类型
 */
@ToString
public class PaginatorHandler<T> {
    // 存储分页的原始数据（使用不可变集合避免外部修改）
    private final List<T> items;
    // 每页显示的条数（必须为正数）
    private final int pageSize;
    // 总页数（缓存计算结果）
    private final int totalPages;
    // 总数据条数
    private final int totalItems;

    /**
     * 构造分页器
     *
     * @param items     待分页的原始数据（null会被转换为空集合）
     * @param pageSize  每页显示的条数（必须>0，否则抛出IllegalArgumentException）
     */
    public PaginatorHandler(List<T> items, int pageSize) {
        // 处理null，转为空集合
        this.items = items == null ? Collections.emptyList() : new ArrayList<>(items);
        // 校验pageSize合法性
        if (pageSize <= 0) {
            throw new IllegalArgumentException("每页条数必须为正数（pageSize > 0），当前值：" + pageSize);
        }
        this.pageSize = pageSize;
        this.totalItems = this.items.size();
        // 计算总页数（缓存）
        this.totalPages = calculateTotalPages();
    }

    /**
     * 获取指定页码的数据
     *
     * @param pageNumber 页码（从1开始，必须>0）
     * @return 该页的数据（空集合表示无数据，不会返回null）
     */
    public List<T> getPage(int pageNumber) {
        // 校验页码合法性
        if (pageNumber <= 0) {
            throw new IllegalArgumentException("页码必须为正数（pageNumber > 0），当前值：" + pageNumber);
        }
        // 页码超出范围时返回空集合
        if (pageNumber > totalPages) {
            return Collections.emptyList();
        }
        // 计算起止索引
        int startIndex = (pageNumber - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, totalItems);
        // 返回新集合（避免外部修改原集合）
        return new ArrayList<>(items.subList(startIndex, endIndex));
    }

    /**
     * 计算总页数
     */
    private int calculateTotalPages() {
        if (totalItems == 0) {
            return 0;
        }
        // 等价于 (totalItems + pageSize - 1) / pageSize，避免浮点数运算
        return (totalItems + pageSize - 1) / pageSize;
    }

    /**
     * 获取总页数
     */
    public Integer getTotalPages() {
        return totalPages;
    }

    /**
     * 获取总数据条数
     */
    public int getTotalItems() {
        return totalItems;
    }

    /**
     * 获取每页显示的条数
     */
    public int getPageSize() {
        return pageSize;
    }

    /**
     * 判断指定页码是否为首页
     *
     * @param pageNumber 页码
     * @return true=是首页（pageNumber=1）
     */
    public boolean isFirstPage(int pageNumber) {
        return pageNumber == 1;
    }

    /**
     * 判断指定页码是否为末页
     *
     * @param pageNumber 页码
     * @return true=是末页（pageNumber=总页数）
     */
    public boolean isLastPage(int pageNumber) {
        // 总页数为0时（无数据），没有末页
        return totalPages > 0 && pageNumber == totalPages;
    }
}
